home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr47
/
dos6mm.zip
/
FILEMON.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-03-31
|
18KB
|
392 lines
;****************************************************************************
; FILEMON monitors the system file table as an aid in determining the
; optimal setting for FILES= in CONFIG.SYS. Its syntax is:
;
; FILEMON
;
; The first time it's run, FILEMON becomes memory-resident so it can track
; file activity in the background. Each time thereafter, it reports the
; number of files that are currently open and the maximum that were open
; at any time since monitoring was begun.
;****************************************************************************
code segment
assume cs:code
org 100h
begin: jmp init
signature db 0,1,2,"FILEMON",2,1,0 ;Program signature
prog_id db ? ;Multiplex ID number
int21h dd ? ;Interrupt 21h vector
int2Fh dd ? ;Interrupt 2FH vector
maxfiles db 0 ;Maximum file open count
lol dd ? ;List of Lists address
;****************************************************************************
; DOS_INT handles calls to interrupt 21h.
;****************************************************************************
dos_int proc far
pushf ;Save FLAGS
cmp ah,3Ch ;Create file?
je dosint1
cmp ah,3Dh ;Open file?
je dosint1
cmp ah,45h ;Duplicate handle?
je dosint1
cmp ah,46h ;Force duplicate handle?
je dosint1
cmp ah,5Ah ;Create temporary file?
je dosint1
cmp ah,5Bh ;Create new file?
je dosint1
cmp ah,6Ch ;Extended open/create?
je dosint1
popf ;Restore FLAGS
jmp cs:[int21h] ;Jump to DOS
;
; Place the call to DOS, then count the number of open files upon return.
;
dosint1: popf ;Restore FLAGS and call DOS
pushf
call cs:[int21h]
pushf ;Save registers
push ax
push cx
push si
push di
push es
sti ;Interrupts on
call count_files ;Count open files
cmp al,cs:[maxfiles] ;Record result if count
jbe dosint2 ;exceeds current maximum
mov cs:[maxfiles],al
dosint2: pop es ;Restore registers
pop di
pop si
pop cx
pop ax
popf
sti ;Enable interrupts
ret 2 ;Exit with FLAGS intact
dos_int endp
;****************************************************************************
; MPLEX_INT handles interrupt 2FH. If, on entry, AH is set to INSTALL's
; multiplex ID number, MPLEX_INT uses the value in AL as a function code.
; The functions supported are:
;
; 00H Returns FFH in AL to indicate the program is installed
; and returns the address of its signature in ES:DI.
;
; 01H Returns the number of files currently open in AL and the
; maximum number of files open concurrently in AH.
;****************************************************************************
mplex_int proc far
pushf ;Save FLAGS register
cmp ah,cs:[prog_id] ;Branch if AH holds the
je mplex2 ;multiplex ID
popf ;Restore FLAGS
jmp cs:[int2Fh] ;Pass the interrupt on
;
; Function 00H verifies that the program is installed.
;
mplex2: popf ;Restore FLAGS
or al,al ;Branch if function code
jnz mplex3 ;is other than 00h
mov al,0FFh ;Set AL to FFh
push cs ;Point ES:DI to the program
pop es ;signature
mov di,offset signature
;
; Function 01H returns the number of open files (current and maximum).
;
mplex3: cmp al,1 ;Exit if function code
jne mplex5 ;is other than 01h
call count_files ;Count open files
cmp al,cs:[maxfiles] ;Record result if count
jbe mplex4 ;exceeds current maximum
mov cs:[maxfiles],al
mplex4: mov ah,cs:[maxfiles] ;Load AH with maximum count
mplex5: iret ;Return from interrupt
mplex_int endp
;****************************************************************************
; COUNT_FILES returns in AL the number of files that are currently open.
;****************************************************************************
count_files proc near
les di,cs:[lol] ;Get List of Lists address
les di,es:[di+4] ;Get address of SFT
xor al,al ;Zero file count
countf1: mov cx,es:[di+4] ;Get count of SFT entries
jcxz countf4 ;Branch if count is zero
mov si,di ;Point SI to the first SFT
add si,6 ;entry in this block
countf2: cmp word ptr es:[si],0 ;Increment count in AL if
je countf3 ;the handle count is not
inc al ;zero
countf3: add si,59 ;Point SI to the next entry
loop countf2 ;Loop until all entries done
countf4: cmp word ptr es:[di],0FFFFh ;Exit if this is the last
je cf_exit ;block in the chain
les di,es:[di] ;Get address of next block
jmp countf1 ;Reenter the loop
cf_exit: ret
count_files endp
;****************************************************************************
; Data that will be discarded when the program becomes memory-resident.
;****************************************************************************
helpmsg db "Tracks file activity as an aid in determining the "
db "optimum setting for the",13,10
db "FILES= statement in CONFIG.SYS.",13,10,"$"
errmsg1 db "Requires DOS 5 or DOS 6",13,10,"$"
errmsg2 db "Program could not be installed"
crlf db 13,10,"$"
copyright db "FILEMON 1.1 Copyright (c) 1993 Jeff Prosise",13,10
db "From: PC Magazine DOS 6 Memory Management "
db "with Utilities",13,10,13,10,"$"
msg1 db "Program installed. Type FILEMON to determine the "
db "number of open files.",13,10,"$"
msg2 db "Files currently open: $"
msg3 db "Maximum thus far: $"
;****************************************************************************
; INIT makes the program resident in memory.
;****************************************************************************
assume cs:code,ds:code
init proc near
cld ;Clear direction flag
mov si,81h ;Point SI to command line
call scanhelp ;Scan for "/?" switch
jnc init1 ;Branch if not found
mov ah,09h ;Display help text and exit
mov dx,offset helpmsg ;with ERRORLEVEL=0
int 21h
mov ax,4C00h
int 21h
;
; Check the DOS version.
;
init1: mov dx,offset errmsg1 ;Error if DOS version
mov ah,30h ;is not 5 or 6
int 21h
cmp al,5
je init2
cmp al,6
je init2
error: mov ah,09h ;Display error message and
int 21h ;exit with ERRORLEVEL=1
mov ax,4C01h
int 21h
;
; Display file status is program is already installed.
;
init2: call check_install ;Branch if the program is
jnc install ;not installed
push ax
mov ah,09h ;Display copyright message
mov dx,offset copyright
int 21h
pop ax
mov al,01h ;Get file statistics
int 2Fh
mov bx,ax ;Transfer the result to BX
mov ah,09h ;Display the number of files
mov dx,offset msg2 ;currently open
int 21h
mov al,bl
xor ah,ah
call bin2asc
mov ah,09h ;Display the maximum file
mov dx,offset msg3 ;count
int 21h
mov al,bh
xor ah,ah
call bin2asc
mov ax,4C00h ;Exit with ERRORLEVEL=0
int 21h
;
; Install the program.
;
install: call mplex_id ;Find a multiplex ID number
mov dx,offset errmsg2 ;Error if none available
jc error
mov prog_id,ah ;Save the ID number
mov ax,3521h ;Hook interrupt 21H
int 21h
mov word ptr int21h,bx
mov word ptr int21h[2],es
mov ax,2521h
mov dx,offset dos_int
int 21h
mov ax,352Fh ;Hook interrupt 2FH
int 21h
mov word ptr int2Fh,bx
mov word ptr int2Fh[2],es
mov ax,252Fh
mov dx,offset mplex_int
int 21h
mov ah,49h ;Free the local block
mov es,ds:[2Ch] ;environment block
int 21h
mov ah,52h ;Get and save the address
int 21h ;of the List of Lists
mov word ptr lol,bx
mov word ptr lol[2],es
mov ah,09h ;Display message verifying
mov dx,offset copyright ;the installation
int 21h
mov ah,09h
mov dx,offset msg1
int 21h
mov ax,3100h ;Terminate with function 31H
mov dx,(offset helpmsg - offset code + 15) shr 4
int 21h
init endp
;****************************************************************************
; SCANHELP scans the command line for a /? switch. If found, carry returns
; set and SI contains its offset. If not found, carry returns clear.
;****************************************************************************
scanhelp proc near
push si ;Save SI
scanloop: lodsb ;Get a character
cmp al,0Dh ;Exit if end of line
je scan_exit
cmp al,"?" ;Loop if not "?"
jne scanloop
cmp byte ptr [si-2],"/" ;Loop if not "/"
jne scanloop
add sp,2 ;Clear the stack
sub si,2 ;Adjust SI
stc ;Set carry and exit
ret
scan_exit: pop si ;Restore SI
clc ;Clear carry and exit
ret
scanhelp endp
;****************************************************************************
; CHECK_INSTALL returns carry set if the program is already installed,
; carry clear if it's not. If carry returns set, AH holds the program's
; multiplex ID number.
;****************************************************************************
check_install proc near
mov ax,0C000h ;Initialize AH and AL
mov cx,40h ;Initialize count
chinst1: push ax ;Save AX and CX
push cx
sub di,di ;Set ES and DI to 0
mov es,di
int 2Fh ;Interrupt 2Fh
cmp al,0FFh ;Nothing here if AL isn't
jne chinst2 ;equal to FFH
mov si,offset signature ;See if program signature
mov cx,13 ;appears at the address
repe cmpsb ;returned in ES:DI
jne chinst2 ;Branch if it does not
pop cx ;Clear the stack and exit
pop ax ;with carry set
stc
ret
chinst2: pop cx ;Retrieve AX and CX
pop ax
inc ah ;Next multiplex ID
loop chinst1 ;Loop until done
clc ;Exit with carry clear
ret
check_install endp
;****************************************************************************
; MPLEX_ID searches for an unused multiplex ID number. If one is found,
; it is returned in AH with carry clear. Carry set means no multiplex
; ID numbers are currently available.
;****************************************************************************
mplex_id proc near
mov ax,0C000h ;Initialize AH and AL
mov cx,40h ;Initialize count
mxid1: push ax ;Save AX and CX
push cx
int 2Fh ;Interrupt 2Fh
or al,al ;Branch if AL=0
jz mxid2
pop cx ;Retrieve AX and CX
pop ax
inc ah ;Increment ID number
loop mxid1 ;Loop until done
stc ;Exit with carry set
ret
mxid2: pop cx ;Clear the stack and exit
pop ax ;with carry clear
clc
ret
mplex_id endp
;****************************************************************************
; BIN2ASC converts a binary value in AX to ASCII form and displays it.
;****************************************************************************
ten dw 10 ;Base 10 divisor
bin2asc proc near
xor cx,cx ;Initialize digit counter
b2a1: inc cx ;Increment digit count
xor dx,dx ;Divide by 10
div ten
push dx ;Save remainder on stack
or ax,ax ;Loop until quotient is zero
jnz b2a1
b2a2: pop dx ;Retrieve a digit from stack
add dl,30h ;Convert it to ASCII
mov ah,2 ;Display it
int 21h
loop b2a2 ;Loop until done
mov ah,09h ;Move the cursor to the
mov dx,offset crlf ;next line
int 21h
ret
bin2asc endp
code ends
end begin